package com.kyleswebspace.propertyanalyzer.gui;

import java.awt.Color;
import java.awt.Font;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.event.FocusEvent;
import java.awt.event.FocusListener;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.text.NumberFormat;

import javax.swing.BorderFactory;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.ToolTipManager;
import javax.swing.border.LineBorder;
import javax.swing.border.TitledBorder;

import com.kyleswebspace.parser.FieldParser;
import com.kyleswebspace.propertyanalyzer.config.ArcaFont;
import com.kyleswebspace.propertyanalyzer.config.BorderBox;
import com.kyleswebspace.propertyanalyzer.config.ColorBox;
import com.kyleswebspace.propertyanalyzer.model.DataModel;

public class PropertyInfoPanel extends JPanel implements Updateable, KeyListener {

	/**
	 * 
	 */
	private static final long serialVersionUID = 3123756836723899629L;
	
	private DataModel dm;
	private FocusMediator fm;
	
	private JLabel addressLabel; 		private JTextField addressField;
	private JLabel numberDoorsLabel; 	private JTextField numberDoorsField;
	private JLabel capRateLabel;		private JTextField capRateField;
	private JLabel appreciationLabel;	private JTextField appreciationField;
	private JLabel askingPriceLabel;	private JTextField askingPriceField;
	private JLabel marketValueLabel;	private JTextField marketValueField;
	private JLabel purchasePriceLabel;	private JTextField purchasePriceField;

	private Color editableColor = ColorBox.fieldColor;
	private Color innerPanelColor = ColorBox.innerPanelColor;
	private Font appFont = ArcaFont.appFont;
	
	public PropertyInfoPanel(DataModel dm, FocusMediator fm) {
		this.dm = dm;
		this.fm = fm;
		dm.register(this);
		
		this.setLayout(new GridBagLayout());
		TitledBorder title;
		title = BorderFactory.createTitledBorder("Property Info");
		this.setBorder(title);
		this.setBackground(innerPanelColor);
		
		GridBagConstraints constraints = new GridBagConstraints();
		//PADDING
		constraints.ipadx = 20;
		
		//address
		addressLabel = new JLabel("Address                                   ");
		addressLabel.setFont(appFont);
		constraints.gridx = 0;
		constraints.gridy = 0;
		constraints.gridwidth = 2;
		constraints.fill = GridBagConstraints.HORIZONTAL;
		constraints.anchor = GridBagConstraints.WEST;
		this.add(addressLabel, constraints);
		addressField = new JTextField(8);
		fm.setAddressField(addressField);
		addressField.addFocusListener(this);
		addressField.addKeyListener(this);
		addressField.setFont(appFont);
		addressField.setHorizontalAlignment(JTextField.RIGHT);
		constraints.gridwidth = 3;
		constraints.fill = GridBagConstraints.NONE;
		constraints.gridx = 1;
		constraints.anchor = GridBagConstraints.EAST;
		addressField.setBackground(editableColor);
		this.add(addressField, constraints);
		
		//number of doors
		numberDoorsLabel = new JLabel("Number of Doors");
		numberDoorsLabel.setFont(appFont);
		constraints.gridx = 0;
		constraints.gridy = 1;
		constraints.gridwidth = 3;
		constraints.anchor = GridBagConstraints.WEST;
		this.add(numberDoorsLabel, constraints);
		numberDoorsField = new JTextField(2);
		fm.setNumberDoorsField(numberDoorsField);
		numberDoorsField.addFocusListener(this);
		numberDoorsField.addKeyListener(this);
		numberDoorsField.setFont(appFont);
		numberDoorsField.setHorizontalAlignment(JTextField.RIGHT);
		constraints.gridwidth = 1;
		constraints.gridx = 3;
		constraints.anchor = GridBagConstraints.EAST;
		numberDoorsField.setBackground(editableColor);
		this.add(numberDoorsField, constraints);
		
		//local cap rate
		capRateLabel = new JLabel("Local Cap Rate");
		capRateLabel.setFont(appFont);
		constraints.gridx = 0;
		constraints.gridy = 2;
		constraints.gridwidth = 3;
		constraints.anchor = GridBagConstraints.WEST;
		this.add(capRateLabel, constraints);
		capRateField = new JTextField(2);
		fm.setLocalCapRateField(capRateField);
		capRateField.addFocusListener(this);
		capRateField.addKeyListener(this);
		capRateField.setFont(appFont);
		capRateField.setHorizontalAlignment(JTextField.RIGHT);
		capRateField.setBorder(BorderBox.fieldBorder);
		capRateField.setToolTipText("<html>Ask a real estate agent specializing in investment properties what the average cap rate is in<br/> " +
				"your area. If you are unable to obtain a number then use the value 0f 8% just to get started<br/> " + 
				"until you are able to find the accurate number. The 7% value may be written over with a true value<br/>" +
				"if you know it. You need a value in this box in order for the analyzer to calculate the \"Market Value\".</html>");
		constraints.gridwidth = 1;
		constraints.gridx = 3;
		constraints.anchor = GridBagConstraints.EAST;
		capRateField.setBackground(editableColor);
		this.add(capRateField, constraints);
		
		//local appreciation
		appreciationLabel = new JLabel("Local Appreciation");
		appreciationLabel.setFont(appFont);
		constraints.gridx = 0;
		constraints.gridy = 3;
		constraints.gridwidth = 3;
		constraints.anchor = GridBagConstraints.WEST;
		this.add(appreciationLabel, constraints);
		appreciationField = new JTextField(2);
		fm.setLocalAppreciationField(appreciationField);
		appreciationField.addFocusListener(this);
		appreciationField.addKeyListener(this);
		appreciationField.setFont(appFont);
		appreciationField.setHorizontalAlignment(JTextField.RIGHT);
		appreciationField.setBorder(BorderBox.fieldBorder);
		appreciationField.setToolTipText("<html>Research what the average rate of appreciation is for the kind of property that you are <br/>" + 
				"looking for in your market. I have put in 3% as a default but you can change this value.</html>");
		constraints.gridwidth = 1;
		constraints.gridx = 3;
		constraints.anchor = GridBagConstraints.EAST;
		appreciationField.setBackground(editableColor);
		this.add(appreciationField, constraints);
		
		//asking price
		askingPriceLabel = new JLabel("Asking Price");
		askingPriceLabel.setFont(appFont);
		constraints.gridx = 0;
		constraints.gridy = 4;
		constraints.gridwidth = 3;
		constraints.anchor = GridBagConstraints.WEST;
		this.add(askingPriceLabel, constraints);
		askingPriceField = new JTextField(4);
		fm.setAskingPriceField(askingPriceField);
		askingPriceField.addFocusListener(this);
		askingPriceField.addKeyListener(this);
		askingPriceField.setFont(appFont);
		askingPriceField.setHorizontalAlignment(JTextField.RIGHT);
		constraints.gridwidth = 2;
		constraints.gridx = 2;
		constraints.anchor = GridBagConstraints.EAST;
		askingPriceField.setBackground(editableColor);
		this.add(askingPriceField, constraints);
		
		//market value
		marketValueLabel = new JLabel("Market Value");
		marketValueLabel.setFont(appFont);
		constraints.gridx = 0;
		constraints.gridy = 5;
		constraints.gridwidth = 3;
		constraints.anchor = GridBagConstraints.WEST;
		this.add(marketValueLabel, constraints);
		marketValueField = new JTextField(4);
		marketValueField.addFocusListener(this);
		marketValueField.setFocusable(false);
		marketValueField.setFont(appFont);
		marketValueField.setBorder(BorderBox.fieldBorder);
		marketValueField.setToolTipText("<html>This value is reverse-computed<br/>" + 
				"based on the cap rate in your area<br/>" +
				"and the net profit of your<br/>" +
				"property. Make sure you have<br/>" +
				"entered a realistic cap rate for<br/>" +
				"your market.</html>");
		marketValueField.setHorizontalAlignment(JTextField.RIGHT);
		constraints.gridwidth = 2;
		constraints.gridx = 2;
		constraints.anchor = GridBagConstraints.EAST;
		this.add(marketValueField, constraints);

		//Purchase Price
		purchasePriceLabel = new JLabel("Purchase Price (PP)     ");
		purchasePriceLabel.setFont(appFont);
		constraints.gridx = 0;
		constraints.gridy = 6;
		constraints.gridwidth = 3;
		constraints.anchor = GridBagConstraints.WEST;
		this.add(purchasePriceLabel, constraints);
		purchasePriceField = new JTextField(4);
		fm.setPurchasePriceField(purchasePriceField);
		purchasePriceField.addFocusListener(this);
		purchasePriceField.addKeyListener(this);
		purchasePriceField.setFont(appFont);
		purchasePriceField.setBorder(BorderBox.fieldBorder);
		purchasePriceField.setToolTipText("<html>Once all the numbers are<br/>" +
				"in place, adjust this<br/>" +
				"number to make the<br/>" +
				"property cash flow. 90%<br/>" +
				"of the asking price is a<br/>" +
				"good place to start.</html>");
		purchasePriceField.setHorizontalAlignment(JTextField.RIGHT);
		constraints.gridwidth = 2;
		constraints.gridx = 2;
		constraints.anchor = GridBagConstraints.EAST;
		purchasePriceField.setBackground(editableColor);
		this.add(purchasePriceField, constraints);
		
		updateFields();
	}
	
	public void updateModel() {
		dm.setAddress(this.addressField.getText());
		dm.setNumberOfDoors(FieldParser.parseInteger(this.numberDoorsField.getText()));
		dm.setLocalCapRate(FieldParser.parseDecimal(this.capRateField.getText()));
		dm.setLocalAppreciation(FieldParser.parseDecimal(this.appreciationField.getText()));
		dm.setAskingPrice(FieldParser.parseInteger(this.askingPriceField.getText()));
		dm.setPurchasePrice(FieldParser.parseInteger(this.purchasePriceField.getText()));
		
		dm.updateInterface();
	}
	
	public void updateFields() {
		this.addressField.setText(dm.getAddress());
		this.numberDoorsField.setText(dm.getNumberOfDoors());
		this.capRateField.setText(dm.getLocalCapRate() + "%");
		this.appreciationField.setText(dm.getLocalAppreciation() + "%");
		this.askingPriceField.setText(dm.getAskingPrice());
		this.marketValueField.setText(dm.getMarketValue());
		this.purchasePriceField.setText(dm.getPurchasePrice());
	}

	@Override
	public void focusGained(FocusEvent e) {
		if (e.getSource() instanceof JTextField) {
			JTextField focusedField = (JTextField)e.getSource();
			focusedField.selectAll();
		}
		
	}

	@Override
	public void focusLost(FocusEvent e) {
		updateModel();
	}

	@Override
	public void keyPressed(KeyEvent e) {
		
		if (e.getSource() == addressField) {
			if (e.getKeyCode() == KeyEvent.VK_DOWN) {
				fm.getNumberDoorsField().requestFocus();
			} else if (e.getKeyCode() == KeyEvent.VK_UP) {
				fm.getLessCashBackField().requestFocus();
			} else if (e.getKeyCode() == KeyEvent.VK_LEFT) {
				fm.getPercentPPCField().requestFocus();
			} else if (e.getKeyCode() == KeyEvent.VK_RIGHT) {
				fm.getRentField().requestFocus();
			}
		} else if (e.getSource() == numberDoorsField) {
			if (e.getKeyCode() == KeyEvent.VK_DOWN) {
				fm.getLocalCapRateField().requestFocus();
			} else if (e.getKeyCode() == KeyEvent.VK_UP) {
				fm.getAddressField().requestFocus();
			} else if (e.getKeyCode() == KeyEvent.VK_LEFT) {
				fm.getPercentPPCField().requestFocus();
			} else if (e.getKeyCode() == KeyEvent.VK_RIGHT) {
				fm.getRentField().requestFocus();
			}
		} else if (e.getSource() == capRateField) {
			if (e.getKeyCode() == KeyEvent.VK_DOWN) {
				fm.getLocalAppreciationField().requestFocus();
			} else if (e.getKeyCode() == KeyEvent.VK_UP) {
				fm.getNumberDoorsField().requestFocus();
			} else if (e.getKeyCode() == KeyEvent.VK_LEFT) {
				fm.getPercentPPCField().requestFocus();
			} else if (e.getKeyCode() == KeyEvent.VK_RIGHT) {
				fm.getParkingField().requestFocus();
			}
		} else if (e.getSource() == appreciationField) {
			if (e.getKeyCode() == KeyEvent.VK_DOWN) {
				fm.getAskingPriceField().requestFocus();
			} else if (e.getKeyCode() == KeyEvent.VK_UP) {
				fm.getLocalCapRateField().requestFocus();
			} else if (e.getKeyCode() == KeyEvent.VK_LEFT) {
				fm.getPaymentTypeCField().requestFocus();
			} else if (e.getKeyCode() == KeyEvent.VK_RIGHT) {
				fm.getLaundryField().requestFocus();
			}
		}  else if (e.getSource() == askingPriceField) {
			if (e.getKeyCode() == KeyEvent.VK_DOWN) {
				fm.getPurchasePriceField().requestFocus();
			} else if (e.getKeyCode() == KeyEvent.VK_UP) {
				fm.getLocalAppreciationField().requestFocus();
			} else if (e.getKeyCode() == KeyEvent.VK_LEFT) {
				fm.getPaymentTypeCField().requestFocus();
			} else if (e.getKeyCode() == KeyEvent.VK_RIGHT) {
				fm.getOtherField().requestFocus();
			}
		} else if (e.getSource() == purchasePriceField) {
			if (e.getKeyCode() == KeyEvent.VK_DOWN) {
				fm.getEnviroReportsField().requestFocus();
			} else if (e.getKeyCode() == KeyEvent.VK_UP) {
				fm.getAskingPriceField().requestFocus();
			} else if (e.getKeyCode() == KeyEvent.VK_LEFT) {
				fm.getAmortizationCField().requestFocus();
			} else if (e.getKeyCode() == KeyEvent.VK_RIGHT) {
				fm.getVacancyRateField().requestFocus();
			}
		}
		
		if (e.getKeyCode() == KeyEvent.VK_ENTER) {
			updateModel();
		}
	}

	@Override
	public void keyReleased(KeyEvent e) {
		
	}

	@Override
	public void keyTyped(KeyEvent e) {

	}
}
